import pickle
from collections import defaultdict
NOTEBOOK_PATH = '/home/fly/notebook/'


def initialize(context):
    run_interval(context, interval_handle, seconds = 3)
    
def before_trading_start(context, data):
    g.security = "600570.SS"
    g.save_flag = False
    g.positions = context.portfolio.positions

    # 设置持久化文件路径
    date_str = context.current_dt.strftime('%Y%m%d')
    file_path = NOTEBOOK_PATH + f'sell_order_record{date_str}.pkl'
    # 现价偏离下单价的幅度
    g.order_adjust_percentile = 0.995
    # 触发下跌直接下单的跌幅
    g.down_thredhold = -5.5
    # 触发下跌策略下单的跌幅
    g.down_observe_thredhold = -2.5
    
    g.stock_sell_list = {"600570.SS": {"sell_thredhold": -3}}

    try:
        with open(file_path, 'rb') as f:
            g.order_dict = pickle.load(f)
    except:
        g.order_dict = defaultdict(list)


def place_sell_order(sell_sid, sid_snapshot, positions):

    # 设置下单数量
    sell_amount = -positions.amount
    # 获取卖一价格和当前价格
    sell1_price = sid_snapshot[sid]['offer_grp'][1][0]
    close_price = sid_snapshot[sid]['close_price']
    # 如果相应的股票ID已经下过单
    if sid in g.order_dict:
        # 如果股票ID的订单状态为8（已成）则直接返回
        if g.order_dict[sid]["status"] == "8":
            return
        # 如果股票ID的订单状态不等于8（已成）
        elif g.order_dict[sid]["status"] != "8":
            # 获取最新的订单信息
            order_id = g.order_dict[sid]["order_id"]
            order_info = get_order(order_id)
            order_status = order_info['status']

            # 如果股票ID的订单状态为8（已成），更新订单状态和持仓信息
            if order_status == "8":
                g.order_dict[sid] = order_info
                g.positions = context.portfolio.positions
                g.save_flag = True
            # 如果股票ID的订单状态不是8（已成），结合交易信息和订单信息判断是否重新下单
            else:
                order_amount = order_info['amount']
                order_filled = order_info['filled']
                limit_price = order_info['limit']
                # 当下单数量不等于已成交数量，且当前价格变化幅度超过之前的下单阈值时，则取消订单，并以最新价格下单
                if order_amount != order_filled and close_price <= g.order_adjust_percentile*limit_price:
                    cancle_order(order_id)
                    limit_price = sell1_price
                    place_order_action(sid, sell_amount, sell1_price)
    # 如果相应的股票ID没有下过单
    elif sid not in g.order_dict:
        # 获取买一价格和当前价格
        place_order_action(sid, sell_amount, limit_price)

    # 如果有订单状态发生变更，则保存订单状态到本地文件，避免策略宕机
    if g.save_flag:
        g.stock_holdings = context.portfolio.positions
        with open(file_path, 'wb') as f:
            pickle.dump(g.order_dict, f, -1)
            g.save_flag = False

def place_order_action(sid, place_amount, limit_price):
    '''
        执行下单操作
    '''
    order_id = order(sid, place_amount, limit_price)
    order_info = get_order(order_id)
    g.order_dict[sid] = order_info
    g.save_flag = True

def trading_signal():
    pass

def interval_handle(context):

    for sid, positions in g.stock_holdings.items():
        sid_snapshot = get_snapshot(sid)
        px_change_rate = sid_snapshot['px_change_rate']

        if px_change_rate <= g.down_thredhold:
            place_sell_order(sid, sid_snapshot, positions)
        # 当涨跌幅没有超过预设阈值，则进行策略下单
        else:
            # 获取当前时间
            end_time = context.current_dt.strftime('%Y%m%d%H%M')        
            # 获取行情价格
            sid_price_df = get_price(sid, start_time, end_time, frequency = '1m', fields = 'close')
    
            # 设置长短周期
            short_period = 5
            long_period = 21
            
            # 获取交易信号
            buy_signal, sell_signal = signal_moving_average(sid_price_df, short_period, long_period)

            if sell_signal == 1 and px_change_rate <= g.down_observe_thredhold:
                place_buy_order(sid, sid_snapshot, g.positions)

def handle_data(context, data):
    pass